package net

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/gorilla/websocket"
)

// websocket服务
type wsServer struct {
	wsConn   *websocket.Conn
	wsRouter *Router
	outChan  chan *WsMsgRsp
	Seq      int64
}

func NewWsServer(wsConn *websocket.Conn) *wsServer {
	return &wsServer{
		wsConn:  wsConn,
		outChan: make(chan *WsMsgRsp, 1000),
		Seq:     0,
	}
}

func (w *wsServer) SetwsRouter(router *Router) {
	w.wsRouter = router
}

// 通道一旦建立 ，那么 收发消息 就得要一直监听才行
func (w *wsServer) Start() {
	//启动读写数据的处理逻辑
	go w.readMsgLoop()
	go w.writeMsgLoop()
}

func (w *wsServer) writeMsgLoop() {
	for {
		select {
		case msg := <-w.outChan:
			w.Write(msg)
		}
	}
}

func (w *wsServer) Write(msg *WsMsgRsp) {
	data, err := json.Marshal(msg.Body)
	if err != nil {
		log.Println(err)
	}
	w.wsConn.WriteMessage(websocket.BinaryMessage, data)
}

func (w *wsServer) readMsgLoop() {
	//先读到客户端 发送过来的数据，然后 进行处理，然后在回消息
	//经过路由 实际处理程序
	defer func() {
		if err := recover(); err != nil {
			log.Fatal(err)
			w.Close()
		}
	}()
	for {

		_, data, err := w.wsConn.ReadMessage()
		if err != nil {
			log.Println("收消息出现错误:", err)
			break
		}
		fmt.Println(data)
		//收到消息 解析消息 前端发送过来的消息 就是json格式
		if err != nil {
			log.Println("解压数据出错，非法格式：", err)
			continue
		}
		body := &ReqBody{}
		err = json.Unmarshal(data, body)
		if err != nil {
			log.Println("数据格式有误，非法格式:", err)
		} else {
			fmt.Println("解析为我们想要的数据:", body)
			// 获取到前端传递的数据了，拿上这些数据 去具体的业务进行处理
			req := &WsMsgReq{Body: body}
			rsp := &WsMsgRsp{Body: &RspBody{Name: body.Name, Seq: body.Seq}}
			w.wsRouter.Run(req, rsp)
			w.outChan <- rsp
		}
	}
	w.Close()
}

func (w *wsServer) Close() {
	_ = w.wsConn.Close()
}
